package org.dxy.trigger.http.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dxy.api.dto.request.workstation.CreateWorkstationRequestDto;
import org.dxy.api.dto.request.workstation.UpdateWorkstationRequestDto;
import org.dxy.api.response.R;
import org.dxy.infrastructure.persistent.db.mybatispuls.po.query.ProductionLineBasicViewPo;
import org.dxy.infrastructure.persistent.db.mybatispuls.po.query.WorkstationBasicViewPo;
import org.dxy.infrastructure.persistent.db.mybatispuls.service.ProductionLineBasicViewService;
import org.dxy.infrastructure.persistent.db.mybatispuls.service.WorkstationBasicViewService;
import org.dxy.trigger.http.service.WorkstationApplicationService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * 工位应用服务实现类
 * @author dxy
 * @createTime 2025/9/4
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class WorkstationApplicationServiceImpl implements WorkstationApplicationService {
    
    private final WorkstationBasicViewService workstationBasicViewService;
    private final ProductionLineBasicViewService productionLineBasicViewService;
    
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Transactional
    @Override
    public R<Void> createWorkstation(CreateWorkstationRequestDto dto) {
        try {
            log.info("开始创建工位: workstationCode={}, workstationName={}, productionLineId={}", 
                    dto.getWorkstationCode(), dto.getWorkstationName(), dto.getProductionLineId());
            
            // 检查产线是否存在
            ProductionLineBasicViewPo productionLine = productionLineBasicViewService.getById(dto.getProductionLineId());
            if (productionLine == null) {
                return R.fail("所属产线不存在");
            }
            
            // 检查工位编码是否已存在
            if (workstationBasicViewService.existsByWorkstationCode(dto.getWorkstationCode())) {
                return R.fail("工位编码已存在");
            }
            
            // 构建位置信息
            String location = buildLocation(productionLine.getFactoryName(), 
                    productionLine.getWorkshopName(), 
                    productionLine.getLineName(), 
                    dto.getWorkstationName());
            
            // 创建工位实体
            WorkstationBasicViewPo workstation = WorkstationBasicViewPo.builder()
                    .workstationCode(dto.getWorkstationCode())
                    .workstationName(dto.getWorkstationName())
                    .productionLineId(dto.getProductionLineId())
                    .productionLineName(productionLine.getLineName())
                    .workshopId(productionLine.getWorkshopId())
                    .workshopName(productionLine.getWorkshopName())
                    .factoryId(productionLine.getFactoryId())
                    .factoryName(productionLine.getFactoryName())
                    .workstationType(dto.getWorkstationType())
                    .status(StringUtils.hasText(dto.getStatus()) ? dto.getStatus() : "IDLE")
                    .capacity(dto.getCapacity())
                    .position(dto.getPosition())
                    .location(location)
                    .supportedProcessTypes(dto.getSupportedProcessTypes())
                    .description(dto.getDescription())
                    .build();
            
            workstationBasicViewService.save(workstation);
            
            log.info("工位创建成功: workstationId={}", workstation.getId());
            return R.ok("工位创建成功");
            
        } catch (Exception e) {
            log.error("创建工位失败", e);
            return R.fail("创建工位失败: " + e.getMessage());
        }
    }

    @Override
    public R<Page<WorkstationBasicViewPo>> list(Page<WorkstationBasicViewPo> page, WorkstationBasicViewPo query) {
        try {
            LambdaQueryWrapper<WorkstationBasicViewPo> queryWrapper = new LambdaQueryWrapper<>();
            
            if (query != null) {
                if (StringUtils.hasText(query.getWorkstationCode())) {
                    queryWrapper.like(WorkstationBasicViewPo::getWorkstationCode, query.getWorkstationCode());
                }
                if (StringUtils.hasText(query.getWorkstationName())) {
                    queryWrapper.like(WorkstationBasicViewPo::getWorkstationName, query.getWorkstationName());
                }
                if (query.getProductionLineId() != null) {
                    queryWrapper.eq(WorkstationBasicViewPo::getProductionLineId, query.getProductionLineId());
                }
                if (query.getWorkshopId() != null) {
                    queryWrapper.eq(WorkstationBasicViewPo::getWorkshopId, query.getWorkshopId());
                }
                if (query.getFactoryId() != null) {
                    queryWrapper.eq(WorkstationBasicViewPo::getFactoryId, query.getFactoryId());
                }
                if (StringUtils.hasText(query.getWorkstationType())) {
                    queryWrapper.eq(WorkstationBasicViewPo::getWorkstationType, query.getWorkstationType());
                }
                if (StringUtils.hasText(query.getStatus())) {
                    queryWrapper.eq(WorkstationBasicViewPo::getStatus, query.getStatus());
                }
            }
            
            queryWrapper.orderByDesc(WorkstationBasicViewPo::getId);
            
            Page<WorkstationBasicViewPo> result = workstationBasicViewService.page(page, queryWrapper);
            return R.ok(result, "查询成功");
            
        } catch (Exception e) {
            log.error("查询工位列表失败", e);
            return R.fail("查询工位列表失败: " + e.getMessage());
        }
    }

    @Transactional
    @Override
    public R<Void> update(Long id, UpdateWorkstationRequestDto dto) {
        try {
            log.info("开始更新工位: workstationId={}", id);
            
            WorkstationBasicViewPo workstation = workstationBasicViewService.getById(id);
            if (workstation == null) {
                return R.fail("工位不存在");
            }
            
            // 检查产线是否存在
            ProductionLineBasicViewPo productionLine = productionLineBasicViewService.getById(dto.getProductionLineId());
            if (productionLine == null) {
                return R.fail("所属产线不存在");
            }
            
            // 构建位置信息
            String location = buildLocation(productionLine.getFactoryName(), 
                    productionLine.getWorkshopName(), 
                    productionLine.getLineName(), 
                    dto.getWorkstationName());
            
            // 更新工位信息
            workstation.setWorkstationName(dto.getWorkstationName());
            workstation.setProductionLineId(dto.getProductionLineId());
            workstation.setProductionLineName(productionLine.getLineName());
            workstation.setWorkshopId(productionLine.getWorkshopId());
            workstation.setWorkshopName(productionLine.getWorkshopName());
            workstation.setFactoryId(productionLine.getFactoryId());
            workstation.setFactoryName(productionLine.getFactoryName());
            workstation.setWorkstationType(dto.getWorkstationType());
            workstation.setStatus(dto.getStatus());
            workstation.setCapacity(dto.getCapacity());
            workstation.setPosition(dto.getPosition());
            workstation.setLocation(location);
            workstation.setSupportedProcessTypes(dto.getSupportedProcessTypes());
            workstation.setDescription(dto.getDescription());

            workstationBasicViewService.updateById(workstation);
            
            log.info("工位更新成功: workstationId={}", id);
            return R.ok("工位更新成功");
            
        } catch (Exception e) {
            log.error("更新工位失败, workstationId={}", id, e);
            return R.fail("更新工位失败: " + e.getMessage());
        }
    }

    @Transactional
    @Override
    public R<Void> delete(Long id) {
        try {
            log.info("开始删除工位: workstationId={}", id);
            
            WorkstationBasicViewPo workstation = workstationBasicViewService.getById(id);
            if (workstation == null) {
                return R.fail("工位不存在");
            }
            
            // TODO: 检查是否有关联的设备或任务
            
            workstationBasicViewService.removeById(id);
            
            log.info("工位删除成功: workstationId={}", id);
            return R.ok("工位删除成功");
            
        } catch (Exception e) {
            log.error("删除工位失败, workstationId={}", id, e);
            return R.fail("删除工位失败: " + e.getMessage());
        }
    }

    @Transactional
    @Override
    public R<Void> batchDelete(List<Long> ids) {
        try {
            log.info("开始批量删除工位: workstationIds={}", ids);
            
            if (ids == null || ids.isEmpty()) {
                return R.fail("工位ID列表不能为空");
            }
            
            // TODO: 检查是否有关联的设备或任务
            
            workstationBasicViewService.removeByIds(ids);
            
            log.info("批量删除工位成功: count={}", ids.size());
            return R.ok("批量删除工位成功");
            
        } catch (Exception e) {
            log.error("批量删除工位失败, workstationIds={}", ids, e);
            return R.fail("批量删除工位失败: " + e.getMessage());
        }
    }

    @Override
    public R<WorkstationBasicViewPo> getById(Long id) {
        try {
            WorkstationBasicViewPo workstation = workstationBasicViewService.getById(id);
            if (workstation != null) {
                return R.ok(workstation, "查询成功");
            } else {
                return R.fail("工位不存在");
            }
        } catch (Exception e) {
            log.error("查询工位详情失败, workstationId={}", id, e);
            return R.fail("查询工位详情失败: " + e.getMessage());
        }
    }

    @Override
    public R<List<WorkstationBasicViewPo>> getByProductionLineId(Long productionLineId) {
        try {
            List<WorkstationBasicViewPo> workstations = workstationBasicViewService.getByProductionLineId(productionLineId);
            return R.ok(workstations, "查询成功");
        } catch (Exception e) {
            log.error("根据产线ID查询工位列表失败, productionLineId={}", productionLineId, e);
            return R.fail("根据产线ID查询工位列表失败: " + e.getMessage());
        }
    }

    @Override
    public R<List<WorkstationBasicViewPo>> getEnabledByProductionLineId(Long productionLineId) {
        try {
            log.info("开始查询产线下启用状态的工位列表: productionLineId={}", productionLineId);
            
            // 检查产线是否存在
            ProductionLineBasicViewPo productionLine = productionLineBasicViewService.getById(productionLineId);
            if (productionLine == null) {
                return R.fail("所属产线不存在");
            }
            
            List<WorkstationBasicViewPo> workstations = workstationBasicViewService.getEnabledByProductionLineId(productionLineId);
            
            log.info("查询产线下启用状态的工位列表成功: productionLineId={}, count={}", productionLineId, workstations.size());
            return R.ok(workstations, "查询成功");
            
        } catch (Exception e) {
            log.error("根据产线ID查询启用状态的工位列表失败, productionLineId={}", productionLineId, e);
            return R.fail("根据产线ID查询启用状态的工位列表失败: " + e.getMessage());
        }
    }
    
    /**
     * 构建位置信息
     */
    private String buildLocation(String factoryName, String workshopName, String lineName, String workstationName) {
        return String.format("%s-%s-%s-%s", factoryName, workshopName, lineName, workstationName);
    }
}